from flask import jsonify, request, Blueprint, redirect, make_response
from utils.myqiniu import send_message
from utils.captcha.captcha import captcha
from utils.myjwt import myjwt
from db import db
from utils.myredis import r
import requests
import random
import time
import json
import datetime
from utils.comm import get_ali_object
user_blue = Blueprint("userblue","__name__")
u_blue = Blueprint("ublue","__name__")

# 获取图片验证码


@user_blue.route("/getImageCode")
def getImageCode():
    # 调用captcha生成图片验证码
    name, text, img = captcha.generate_captcha()
    # 存入redis 字符串 key :uuid value:text
    uuid = request.args.get('uuid')
    r.str_setex(uuid, text, 300)
    res = make_response(img)
    res.headers['Content-Type'] = "image/jpg"
    return res


# 发送短信接口
@user_blue.route("/sendsms", methods=["POST"])
def sendsms():
    # 获取参数mobil、uuid、imagecode
    data = json.loads(request.data)
    print(">>>", data)
    mobile = data["mobile"]
    uuid = data["uuid"]
    print(">>>>", uuid)
    imagecode = data["imagecode"]
    if not all([mobile, imagecode, uuid]):
        return jsonify({"code": 20010, "msg": "参数不完整"})
    # 验证图片验证码
    code = r.str_get(uuid)
    # 通过uuid从redis取出来和传递过来的参数在对比，全部转为小写
    if code:
        if imagecode.lower() != code.decode().lower():
            return jsonify({"code": 20011, "msg": "图片验证码错误"})
        # 清除redis中的图片验证码
        r.del_key(uuid)
    else:
        return jsonify({"code": 20013, "msg": "没有获取到图片验证码"})
    # 1分钟内只能发送一次
    v = r.str_get(mobile)
    if v:
        return jsonify({"code": 20014, "msg": "一分钟内只能发送一次"})
    # 如果成功调用写入redis队列
    r.list_push("smsmobile", mobile)
    # 短信接口qps每秒请求100
    return jsonify({"code": 200, "msg": "ok"})

# 手机验证码


@user_blue.route("/send1")
def send1():
    while True:
        # 查看队列长度，如果没值不处理
        for i in range(2):
            len = r.list_len("smsmobile")
            if len > 0:
                value = r.list_pop("smsmobile")
                mobile = value.decode()
                # 如果长度大于1
                code = random.randint(1000, 9999)
                print(code)
                print(">>>>>>>>>>")
                res = send_message(mobile, code)
                print(">>>>>>>>>>>>>>>>>>>>>>>>>>>", res)
                # 判断是否成功，成功写入redis
                r.str_setex(mobile, code, 60)
        time.sleep(1)
        return jsonify({"code": 200, "msg": "获取验证码成功", "sms": code})

# 登录接口


@user_blue.route("/login", methods=["POST"])
def login():
    # 获取手机号和验证码
    data = json.loads(request.data)
    mobile = data["mobile"]
    code = data["code"]
    print(mobile)
    # 获取验证码进行判断
    codemes = r.str_get(mobile)
    if codemes:
        if str(codemes.decode()) != str(code):
            return jsonify({"code": 10030, "msg": "验证码错误"})
        # 清除验证码
        r.del_key(mobile)
        # 通过手机号查询数据库
        sql = "select * from users where mobile='%s'" % (mobile)
        user = db.findone(sql)
        # 返回用户信息
        if user:
            # 调用jwt、encode生成token
            data = {"data": {"userid": user["id"], "mobile": [
                "mobile"], "exptime": int(time.time())}}
            token = myjwt.jwt_encode(data)
            return jsonify({"code": 200, "msg": "登陆成功", "token": token, "userid": user["id"]})
        return jsonify({"code": 201, "msg": "没有该用户"})


@u_blue.route("/getWBurl")
def getWBurl():
    client_id = "3674019597"
    redirect_uri = "http://127.0.0.1:8000/user/weiboCallback/"
    url = "https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code" % (
        client_id, redirect_uri)
    return jsonify({"code": 200, "url": url})


# 微博回调接口
@u_blue.route("/weiboCallback/")
def weiboCallback():
    # 获取code
    code = request.args.get("code")
    # 向access_token接口发送post请求
    data = {"client_id": '3674019597', "client_secret": "7ae99bc0d54ead29fc8d1b9fabd78587",
            "grant_type": "authorization_code",
            'redirect_uri': 'http://127.0.0.1:8000/user/weiboCallback/', 'code': code}
    res = requests.post('https://api.weibo.com/oauth2/access_token', data=data)
    # 根据返回结果操作
    # 获取token和uid
    message = json.loads(res.text)
    token = message['access_token']
    uid = message['uid']
    # 查询数据库中是否存在，如果存在用用户信息生成jwt token返回
    sql = "select users.id,users.mobile from sf_login inner join users on sf_login.userid=users.id where sf_login.uid='%s'" % (
        str(uid))
    user = db.findone(sql)
    if user:
        # 生成jwt
        # 返回jwt token
        token = myjwt.jwt_encode(
            data={"data": {"uid": user['id'], "mobile": user['mobile'], 'exp': int(time.time())}})
        return redirect("http://localhost:8080/#/updatetoken?token="+token+"&userid="+str(user['id']))

    else:
        # 绑定
        return redirect("http://localhost:8080/#/wbzz?token="+str(token)+"&uid="+str(uid))


# 绑定
@u_blue.route("/bindM/", methods=['POST'])
def bindM():
    # 接收参数
    data = json.loads(request.data)
    # 加入用户表
    sql = "insert into users(name,mobile) values('%s','%s')" % (
        data['name'], data['mobile'])
    userid = db.add(sql)
    # 加入三方登录表
    sql2 = "insert into sf_login(userid,webfrom,uid,token) values(%d,'weibo','%s','%s')" % (
        userid, data['uid'], data['token'])
    db.add(sql2)
    db.commit()
    # 返回jwt token
    token = myjwt.jwt_encode(data={"data": {
                             "uid": userid, "mobile": data['mobile'], "name": data['name'], 'exp': int(time.time())}})
    return jsonify({"code": 200, "token": token, "userid": userid})



#加入购物车
@user_blue.route("/addcart",methods=['POST'])
def addcart():
    #获取参数
    data = json.loads(request.data)
    userid = data['userid']
    goodsid = data['goodsid']
    #调用redis add hash进行添加
    pkey = "mycart"+str(userid)
    r.hash_add(pkey,goodsid,1)
    return jsonify({"code":200,"msg":"加入购物车成功"})

# 我的购物车
@user_blue.route("/getcart")
def getcart():
    userid = request.args.get("userid")
    pkey = "mycart"+str(userid)
    print(">>>>>",pkey)
    res = r.hash_getall(pkey)
    print(">>>",res)
    for i,j in res.items():
        goodsid = i.decode()
        sql = "select id,name,price from courses where id=%d"%int(goodsid)
        res = db.findone(sql)
    return jsonify({"code": 200, "msg":"ok","data": res})

# 生成订单
@user_blue.route("/addorder", methods=["POST"])
def addorder():
    data = json.loads(request.data)
    userid = int(data["userid"])
    courseid = int(data["courseid"])
    print("userid",userid)
    sum=0
    orderno = str(int(time.time()))+str(userid)+str(random.randint(10000,99999))
    try:
        sql = "select * from courses where id= %d"%courseid
        res = db.findone(sql)
        sum += float(res["price"])
        #添加详情表
        sql1 = "insert into order_desc(number,coursesid,name,price,img,usersid) values('%s',%d,'%s','%s','%s',%d)"%(orderno,courseid,res["name"],sum,res["img"],userid)
        db.add(sql1)
        #添加订单表
        create_time = datetime.datetime.strftime(
                datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")
        sql2 = "insert into order1(number,price,create_time,status,usersid) values('%s','%s','%s',%d,%d)"%(orderno,sum,create_time,1,userid)
        db.add(sql2)
        db.commit()
        return jsonify({"code":200, "msg":"OK"})
    except Exception as a:
        print(">>>>>>>>>>>>>>>>>>",a)
        db.rollback()
        return jsonify({"code":400, "msg":"错误"})

# 支付
@user_blue.route('/coursepay')
def coursepay():
    userid = int(request.args.get("userid"))
    goodsid = int(request.args.get("goodsid"))
    print("userid>>>>",userid,goodsid)
    sql = """select * from order1 where id=%d""" % (goodsid)
    goodsids = db.findone(sql)
    price = float(goodsids['price'])
    print("price>>>",price)

    # 支付
    alipay = get_ali_object()
    query_params = alipay.direct_pay(
        subject=str(userid) + "购买课程服务",  # 商品简单描述
        out_trade_no=str(goodsids['number']) + ",2",  # 用户购买的商品订单号（每次不一样） 20180301073422891
        total_amount=price,  # 交易金额(单位: 元 保留俩位小数)
    )
    pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
    return jsonify({
        'code': 200,
        'url': pay_url
    })


@user_blue.route("/callback")
def callback():
    trade_no = request.args.get('trade_no')  # 流水号
    out_trade_no = request.args.get('out_trade_no')  # 订单号
    ordernolist = out_trade_no.split(',')
    if int(ordernolist[1]) == 2:
        # 购买课程，更新课程订单表，写入用户课程表
        updateCourse(ordernolist[0], trade_no)
    if int(ordernolist[1]) == 3:
        # 购买课程，更新课程订单表，写入用户课程表
        updatecommodity(ordernolist[0], trade_no)
    # 跳转到个人中心特免
    return redirect('http://localhost:8080/#/')


def updateCourse(ordernolist, trade_no):
    try:
        print(trade_no)
        a_time = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")
        sql = """update order1 set status=2,pay_time='%s',serial_number='%s' where id=%d""" % (
        a_time, trade_no, int(ordernolist))
        db.add(sql)
        sqlss = """select * from order1 where id=%d""" % (int(ordernolist))
        orders = db.findone(sqlss)
        userid = int(orders['usersid'])
        numbers = orders['number']
        csql = """select * from order_desc where number=('%s')""" % (numbers)
        res = db.findone(csql)
        courseid = res['coursesid']
        print(">>>>>>>>>>>>>>", courseid)
        sqls = """insert into user_courses(userid,courseid) values(%d,%d)""" % (userid, int(courseid))
        db.add(sqls)
        db.commit()
    except Exception as e:
        print('>>>>>>>>>>>>>>>>>>>>', e)
        db.rollback()


# 获取训练营
@user_blue.route("/getcommodity")
def getcommodity():
    sql = "select * from commodity"
    res = db.find_all(sql)
    for i in res:
        i["price"] = float(i["price"])
        i["create_time"] = datetime.datetime.strftime(i["create_time"], "%Y-%m-%d %H:%M:%S")
    return jsonify({"code": 400, "msg": "ok", "data": res})


# 生成订单
@user_blue.route("/postcommodity", methods=["POST"])
def postcommodity():
    data = json.loads(request.data)
    userid = int(data["userid"])
    id = int(data["id"])
    count = int(data["count"])
    lock_store = int(data["lock_store"])
    # 订单号
    number = str(int(time.time())) + str(userid) + str(random.randint(10000, 99999))
    res = "select * from commodity where id=%d and inventory-%d >=%d" % (id, lock_store, count)
    res1 = db.findone(res)
    # 生成订单时间
    create_times = datetime.datetime.strftime(
        datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")
    count_price = 0
    if res1:
        # 总价
        # print("price",res1["price"])
        count_price = float(res1["price"]) * count
        # print("count_price",count_price)
        try:
            # 写入订单表
            sql = "insert into commodity_order(number,count,count_price,create_times,status,goodid,goods_name,goods_price,goods_img,usersid) values('%s',%d,'%s','%s',%d,%d,'%s','%s','%s',%d)" % (
            number, count, count_price, create_times, 1, id, res1["name"], float(res1["price"]), res1["img"], userid)
            db.add(sql)
            # 更新锁定库存
            # 锁定数量
            but_count = lock_store + count
            print("but_count", but_count)
            # 库存
            inventory = int(res1["inventory"]) - count
            # print("inventory",inventory)
            sql1 = "update commodity set lock_store=%d,inventory=%d where id=%d" % (but_count, inventory, id)
            db.add(sql1)
            db.commit()
            print("userid", userid)
            print("count_price", count_price)
            print("id", id)
            # 支付
            alipay = get_ali_object()
            query_params = alipay.direct_pay(
                subject=str(userid) + "购买课程服务",  # 商品简单描述
                out_trade_no=str(number) + ",3",  # 用户购买的商品订单号（每次不一样） 20180301073422891
                total_amount=count_price,  # 交易金额(单位: 元 保留俩位小数)
            )
            pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
            return jsonify({
                'code': 200,
                'url': pay_url
            })
        except Exception as a:
            print(">>>>>>>>>>>", a)
            db.rollback()
            return jsonify({"code": 400, "msg": "加入订单错误"})


def updatecommodity(ordernolist, trade_no):
    print("ordernolist", ordernolist)
    sql = "select * from commodity_order where number=%d" % int(ordernolist)
    res = db.findone(sql)
    number = int(res["number"])
    goodid = int(res["goodid"])
    conut = int(res["count"])
    sql1 = "select * from commodity where id=%d" % goodid
    res1 = db.findone(sql1)
    lock_store = int(res1['lock_store'])
    try:
        print(trade_no)
        a_time = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")
        # 跟新订单表订单状态
        sql2 = """update commodity_order set status=2,pay_times='%s',serial_numbers='%s' where number=%d""" % (
        a_time, trade_no, number)
        db.add(sql2)
        # 跟新锁定库存
        lock = lock_store - conut
        sql3 = "update commodity set lock_store=%d where id=%d" % (lock, goodid)
        db.add(sql3)
        db.commit()
    except Exception as e:
        print('>>>>>>>>>>>>>>>>>>>>', e)
        db.rollback()


# 获取订单
@user_blue.route("/getorder")
def getorder():
    userid = request.args.get("userid")
    sql = "select * from order1 where usersid=%d"%int(userid)
    res = db.find_all(sql)
    for i in res:
        i["price"]=float(i["price"])
        i["create_time"]=datetime.datetime.strftime(i["create_time"],"%Y-%m-%d %H:%M:%S")
    return jsonify({"code":200, "msg":"OK","data":res})


from elasticsearch import Elasticsearch
es = Elasticsearch(hosts="http://43.143.162.69:9200/")
@user_blue.route("/getsex")
def getsex():
    res = {
        "query":{
            "match":{"sex":"男"}
        }
    }
    res1 = es.search(index='user5',body=res)
    return jsonify({"code": 200,"msg":"OK","data":res1['hits']['hits']})

@user_blue.route("/getsexs")
def getsexs():
    res = {
        "query":{
            "match":{"sex":"女"}
        }
    }
    res1 = es.search(index='user5',body=res)
    return jsonify({"code": 200,"msg":"OK","data":res1['hits']['hits']})

@user_blue.route("/getage")
def getage():
    gte = request.args.get("gte")
    lte = request.args.get("lte")
    res = {
        "query":{
            "bool":{
                "should":[
                    {"match":{"age":1}},
                ],
                "filter":{
                    "range":{
                    "age":{
                        "gte":gte,
                        "lte":lte
                    }
                }
            }
        }
        },
        "_source":["age"],
    }
    res1 = es.search(index="user5",body=res)
    return jsonify({"code": 200,"msg":"OK","data":res1['hits']['hits']})

@user_blue.route("/getname")
def getname():
    # 获取
    name = request.args.get("name")
    print(name)
    # 第几页数据
    page = request.args.get("currentPage")
    # 获取几条数据
    page_size = request.args.get('page_size')
    # 获取从哪到哪的数据
    start = (int(page)-1)*int(page_size)
    res = {
        "query":{
            "match":{"name":name}
        },
        "from":start,
	    "size":page_size,
        "sort":{
            "id":{
                "order":"desc"
            }
        }
    }
    ress = {
        "query":{
            "match":{"name":name}
        },
    }
    res1 = es.search(index='user5',body=res)
    count = es.count(index="user5",body=ress)
    total = count['count']
    return jsonify({"code": 200,"msg":"OK","total":total,"data":res1['hits']['hits']})


# 添加角色
@user_blue.route("/addrole", methods=["post"])
def addrole():
    data = json.loads(request.data)
    sql = "insert into roles(name) values ('%s')" % (data["name"])
    db.add(sql)
    db.commit()
    return jsonify({"code": 200, "msg": "ok"})


# 添加用户
@user_blue.route("/adduser", methods=["post"])
def adduser():
    data = json.loads(request.data)
    sql = "insert into user(name,roleid) values ('%s',%d)" % (data["name"], int(data["id"]))
    db.add(sql)
    db.commit()
    return jsonify({"code": 200, "msg": "ok"})


# 添加资源
# @user_blue.route("/addresource",methods=["post"])
# def addresource():
#     data = json.loads(request.data)
#     sql = "insert into resource(name,pid) values ('%s',%d)"%(data["name"],int(data["pid"]))
#     db.add(sql)
#     db.commit()
#     return jsonify({"code":200, "msg":"ok"})

# 左边栏
@user_blue.route("/getzuo")
def getzuo():
    sql = "select * from resource where pid=0"
    res = db.find_all(sql)
    return jsonify({"code": 200, "msg": "ok", "data": res})


# 左边栏
@user_blue.route("/getss")
def getss():
    id = request.args.get("id")
    sql = "select * from resource where pid=%d" % (int(id))
    res = db.find_all(sql)
    return jsonify({"code": 200, "msg": "ok", "data": res})


# 配置资源
@user_blue.route("/getpower")
def getpower():
    sql = "select * from power"
    res = db.find_all(sql)
    lst = [{"key": i["id"], "label": i["name"]} for i in res]
    return jsonify({"code": 200, "msg": "ok", "data": lst})


@user_blue.route("/setRoleResoure", methods=["POST"])
def setRoleResoure():
    data = json.loads(request.data)
    roleid = int(data['roleid'])
    resourcelist = data['resourcelist']
    # 删除此角色对应的资源
    sql = "delete from role_resource where roleid=%d" % (roleid)
    db.add(sql)
    db.commit()
    # 一一添加
    print(resourcelist)
    for i in resourcelist:
        sql1 = "insert into role_resource(roleid,resourceid) values(%d,%d)" % (roleid, int(i))
        db.add(sql1)
        db.commit()
    return jsonify({"code": 200, "msg": "添加成功"})


# 添加资源
@user_blue.route("/addpower", methods=["POST"])
def addpower():
    data = json.loads(request.data)
    name = data['name']
    sql = "insert into power(name) values ('%s')" % (name)
    db.add(sql)
    db.commit()
    return jsonify({"code": 200, "msg": "添加成功"})


# 获取角色
@user_blue.route("/getrole")
def getrole():
    sql = "select * from roles"
    res = db.find_all(sql)
    return jsonify({"code": 200, "msg": "获取成功", "data": res})


@user_blue.route("/setResource1", methods=["POST"])
def setResource1():
    data = json.loads(request.data)
    roleid = data['roleid']
    parentRole = data['parentRole']
    print("parentRole",parentRole)
    reslist = data['reslist']
    print("reslist",reslist)
    # 互斥
    for i in reslist:
        print("i",i)
        res = "select * from mutual where resourceid1=%d"%(int(i))
        ress = db.find_all(res)
        print("res",ress)
        for j in ress:
            print("j",j)
            print("j",j["resourceid2"])
            if j["resourceid2"] in reslist:
                return jsonify({"code": 400, "msg":"资源出现互斥,请重新添加"})
    #删除此角色对应的所有资源
    sql = "delete from roles_resources where roleid=%d"%(int(roleid))
    db.add(sql)
    rr = []
    #判断继承角色是否大于0,如果大于查询继承资源
    if parentRole and int(parentRole)>0:
        sql1 = "select resourceid from roles_resources where roleid=%d"%(int(parentRole))
        rr = db.find_all(sql1)
        print("rr",rr)
        lst = []
        for i in rr:
            resourceid = i["resourceid"]
            lst.append(resourceid)
        print("reslist",reslist)
        #查新当前角色继承的角色
        sql3 = "update roles set pid=%d where id=%d"%(int(parentRole),int(roleid))
        db.add(sql3)
        #获取配制资源reslist,取并集去重
        resourcelist = set(lst+reslist)
        #更新角色资源表
        for i in resourcelist:
            sql2 = "insert into roles_resources values(%d,%d)"%(int(roleid),int(i))
            db.add(sql2)
    else:
        #查新当前角色继承的角色
        sql3 = "update roles set pid=%d where id=%d"%(int(parentRole),int(roleid))
        db.add(sql3)
        for i in reslist:
            sqll = "insert into roles_resources(roleid,resourceid) values(%d,%d)"%(roleid,int(i))
            db.add(sqll)
    db.commit()
    return jsonify({"code":200,"msg":"添加成功"})

# 获取此角色已经配制过的资源
@user_blue.route("/getRoleResoure")
def getRoleResoure():
    id = request.args.get("id")
    print("id",id)
    sql = "select resourceid from roles_resources where roleid=%d"%(int(id))
    res = db.find_all(sql)
    list = [i['resourceid'] for i in res]
    print("list",list)
    #重组数据返回
    return jsonify({"code":200,'data':list})


@user_blue.route("/getMonthMoney")
def getMonthMoney():
    sql = "select sum(price) as tmoney,date_format(pay_time,'%Y-%m') as month from order1 group by month"
    res = db.find_all(sql)
    list1=[]
    list2=[]
    for i in res:
        list1.append(float(i['tmoney']))
        list2.append(i['month'])
    return jsonify({"code":200,'list1':list1,'list2':list2})


@user_blue.route("/setwork", methods=["POST"])
def setwork():
    data = json.loads(request.data)
    print(data["name"])
    sql = "insert into work(name, params) values('%s','%s')" % (data["name"], data["params"])
    db.add(sql)
    db.commit()
    return jsonify({"code": 200, "msg": "添加成功"})


@user_blue.route("/getrole")
def getrole():
    sql = "select * from role"
    res = db.find_all(sql)
    lst = [{"key": i["id"], "label": i["name"]} for i in res]
    return jsonify({"code": 200, "msg": "获取成功", "data": lst})


@user_blue.route("/getwork")
def getwork():
    sql = "select id,name from work"
    res = db.find_all(sql)
    return jsonify({"code": 200, "msg": "获取成功", "data": res})


@user_blue.route("/updatework", methods=["POST"])
def updatework():
    data = json.loads(request.data)
    id = int(data["id"])
    auditlist = data["auditlist"]
    print(data["auditlist"])
    for i in auditlist:
        sql = "update work set auditlist='%s' where id=%d" % (int(i), id)
        db.add(sql)
    db.commit()
    return jsonify({"code": 200, "msg": "修改成功"})